package com.ltmall.api.controller;

//import com.ali.dayu.Code;
//import com.ali.dayu.MSGManager;

import com.google.gson.Gson;
import com.ltmall.api.bean.*;
import com.ltmall.api.comm.Path;
import com.ltmall.api.entity.JsonWallet;
import com.ltmall.api.manager.AccountManager;
import com.ltmall.api.manager.MembershipManager;
import com.ltmall.api.manager.SubUnderwritingManager;
import com.ltmall.api.manager.WalletManager;
import com.ltmall.api.util.PageUtil;
import com.ltmall.api.util.RemoteUtil;
import com.ltmall.api.weixin.pay.Constants;
import com.ltmall.api.weixin.pay.utils.WeixinUtils;
import com.ltmall.api.weixin.pay.utils.WeixinUtils.WXPayType;
import com.ltmall.api.weixin.tecent.comm.RandomStringGenerator;
import com.ltmall.api.weixin.util.TemplateMessageUtil;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.stereotype.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
public class WalletController {

    /**
     * The vali tag.
     */
    boolean opTag, valiTag;

    /**
     * The wallet manager.
     */
    private WalletManager walletManager;

    /**
     * The account manager.
     */
    private AccountManager accountManager;
    private MembershipManager clientManager;
    private SubUnderwritingManager subUnderwritingManager;

    private Logger logger = LogManager.getLogger(WalletController.class);

    public SubUnderwritingManager getSubUnderwritingManager() {
        return subUnderwritingManager;
    }

    public void setSubUnderwritingManager(SubUnderwritingManager subUnderwritingManager) {
        this.subUnderwritingManager = subUnderwritingManager;
    }

    /**
     * Gets the account manager.
     *
     * @return the account manager
     */
    public AccountManager getAccountManager() {
        return accountManager;
    }

    /**
     * Sets the account manager.
     *
     * @param accountManager the new account manager
     */
    public void setAccountManager(AccountManager accountManager) {
        this.accountManager = accountManager;
    }

    /**
     * Gets the wallet manager.
     *
     * @return the wallet manager
     */
    public WalletManager getWalletManager() {
        return walletManager;
    }

    /**
     * Sets the wallet manager.
     *
     * @param walletManager the new wallet manager
     */
    public void setWalletManager(WalletManager walletManager) {
        this.walletManager = walletManager;
    }

    public MembershipManager getClientManager() {
        return clientManager;
    }

    public void setClientManager(MembershipManager clientManager) {
        this.clientManager = clientManager;
    }

    /**
     * 获取钱包信息。
     *
     * @param request  the request
     * @param response the response
     */
    public void userWalletGet(HttpServletRequest request, HttpServletResponse response) {
        String userID = request.getParameter("userID");
        String userToken = request.getParameter("userToken");
        if (userID != null && userID != "") {
            ThHcWallet userWallet = walletManager.getWalletByUser(Integer.parseInt(userID));
            if (userWallet != null) {
                RemoteUtil.response(response, userWallet, 1, "操作成功");
            } else {
                RemoteUtil.response(response, "", -1, "找不到用户");
            }
        } else {
            RemoteUtil.response(response, "", -1, "参数缺失");
        }
    }

    /**
     * 获取充值渠道和汇率。
     *
     * @param request  the request
     * @param response the response
     */
    public void rechargeChannelGet(HttpServletRequest request, HttpServletResponse response) {
        String channelID = request.getParameter("channelID");
        String userToken = request.getParameter("userToken");
        if (channelID != null && channelID != "") {
            ThRechargeChannel channel = walletManager.getRechargeChannelByID(Integer
                    .parseInt(channelID));
            RemoteUtil.response(response, channel, 1, "操作成功");
        } else {
            RemoteUtil.response(response, "", -1, "参数缺失");
        }
    }

    /**
     * 获取充值渠道列表。
     *
     * @param request  the request
     * @param response the response
     */
    public void rechargeChannelListGet(HttpServletRequest request, HttpServletResponse response) {
        List<ThRechargeChannel> channelList = walletManager.getRechargeChannelList();
        RemoteUtil.response(response, channelList, 1, "操作成功");
    }

    /**
     * 获取用户充值记录。
     *
     * @param request  the request
     * @param response the response
     */
    public void userRechargeRecordsGet(HttpServletRequest request, HttpServletResponse response) {
        String userID = request.getParameter("userID");
        PageUtil page = new PageUtil(Integer.parseInt(request.getParameter("page")));
        if (userID != null && userID != "") {
            // 拿userID取充值记录，并按时间降序排列
            List<ThRechargeRecord> recordList = walletManager.getRechargeRecordsByUser(
                    Integer.parseInt(userID), page);
            RemoteUtil.response(response, recordList, 1, "操作成功");
        } else {
            RemoteUtil.response(response, "", -1, "参数缺失");
        }
    }

    /**
     * 充值接口。
     *
     * @param request  the request
     * @param response the response
     */
    public void rechargeRecordCreate(HttpServletRequest request, HttpServletResponse response) {
        String userID = request.getParameter("userID");
        String userToken = request.getParameter("userToken");
        String userName = request.getParameter("userName");
        String amounts = request.getParameter("amounts"); // 乡币金额
        String channel = request.getParameter("channel"); // 渠道 (1:现金支付，2:乡情红包兑换)
        String subUndId = request.getParameter("subUndId"); // 红包ID = 用户ID

        if (userID == null || userID == "" || userName == null || userName == "" || amounts == null
                || amounts == "" || channel == null || channel == "") {
            RemoteUtil.response(response, null, -1, "参数缺失");
            return;
        }
        // 验本站token
        valiTag = accountManager.validate(Integer.parseInt(userID), userToken);
        if (!valiTag) {
            RemoteUtil.response(response, null, -100, "身份异常");
            return;
        }
        // 生成交易号
        String out_trade_no = WeixinUtils.getOut_trade_no();
        // 获取渠道信息
        ThRechargeChannel channelInfo = walletManager.getRechargeChannelByID(Integer
                .parseInt(channel));
        // 计算乡币汇率
        BigDecimal hcAmounts = new BigDecimal(amounts);
        BigDecimal exchange = channelInfo.getExchange();
        BigDecimal payAmounts = hcAmounts.multiply(exchange);
        int payAmountsInt = payAmounts.multiply(new BigDecimal(100))
                .setScale(2, BigDecimal.ROUND_HALF_UP).intValue();
        int amountsInt = hcAmounts.multiply(new BigDecimal(100))
                .setScale(2, BigDecimal.ROUND_HALF_UP).intValue();
        // 充值金额小于一角则拒绝
        if (amountsInt < 10) {
            RemoteUtil.response(response, null, -1, "金额不可小于0.1元");
            return;
        }
        // 输出测试
        System.out.println(amountsInt);
        System.out.println(payAmountsInt);
        System.out.println(Integer.parseInt(channel));
        System.out.println("HC" + System.currentTimeMillis());
        System.out.println(out_trade_no);
        System.out.println(new java.util.Date(System.currentTimeMillis()));
        System.out.println(Integer.parseInt(userID));
        System.out.println(userName);
        System.out.println(subUndId);
        // 组装充值记录
        ThRechargeRecord record = new ThRechargeRecord();
        // 充值的乡币数（分）
        record.setAmounts(amountsInt);
        // 渠道金额，要支付的钱，以分为单位
        record.setChannelAmounts(payAmountsInt);
        record.setChannel(Integer.parseInt(channel));
        // HCINCOME + 时间戳
        record.setSn("HC" + System.currentTimeMillis());
        // 充值中
        record.setState(1);
        // 生成交易号
        record.setOutTradeNo(out_trade_no);
        record.setCreatedAt(new java.util.Date(System.currentTimeMillis()));
        record.setUserId(Integer.parseInt(userID));
        record.setUserName(userName);
        record.setPaidAt(new java.util.Date(System.currentTimeMillis()));
        // 插入充值记录
        Boolean opTag = walletManager.rechargeRecordCreate(record);
        if (opTag) {
            if (Integer.parseInt(channel) == 1) {
                // 现金支付
                String ip = getIpAddr(request);
                String body = "乡味汇订单";
                wxOAPay(payAmountsInt, body, ip, out_trade_no, request, response);
                //				 wxHcNotifyTest(out_trade_no, String.valueOf(payAmountsInt));
                //				 RemoteUtil.response(response, "", 1, "预存成功");
            } else if (Integer.parseInt(channel) == 2) {
                // 红包兑换
                if (subUndId != "" && subUndId != null) {
                    // 获取原出账金额
                    ThSubUnderwriters subUnderwriters = subUnderwritingManager
                            .subUnderwriterGet(Integer.parseInt(subUndId));
                    try {
                        ThHcWallet wallet = walletManager.getWalletByUser(Integer.parseInt(userID));
                        int amount = wallet.getAvaileAmounts() + payAmountsInt;
                        // 更新充值记录状态
                        walletManager.rechargeRecordUpdate(out_trade_no, 2);
                        // 修改乡币账户金额（乡情红包兑换不需要冻结部分金额）
                        walletManager
                                .hcWalletAvaileUpdateByUserID(amount, Integer.parseInt(userID));
                        // 增加[红包]出账金额
                        subUnderwritingManager.subUnderwriterTotalOutcomeUpdate(
                                Integer.parseInt(subUndId),
                                subUnderwriters.getTotalOutcome().add(payAmounts));
                        // 增加[红包]出账记录
                        subUnderwritingManager.subUnderwritingOutcomeAdd(
                                Integer.parseInt(subUndId), payAmounts, 1, record.getId(), 1);
                    } catch (Exception e) {
                        RemoteUtil.response(response, "", -1, "红包兑换失败");
                    }
                    RemoteUtil.response(response, "", 1, "红包兑换成功");
                } else {
                    RemoteUtil.response(response, "", -1, "缺少红包参数");
                }
            } else {
                RemoteUtil.response(response, "", -1, "无法识别的渠道编号");
            }
        } else {
            RemoteUtil.response(response, "", -1, "充值记录创建失败");
        }
    }

    /**
     * 微信支付签名生成。
     *
     * @param request  the request
     * @param response the response
     */
    public void wxOAPay(int totalPrice, String body, String ip, String out_trade_no,
                        HttpServletRequest request, HttpServletResponse response) {
        System.out.println("----创建微信预付定单-----");
        try {
            System.out.println("totalPrice--->" + totalPrice);
            System.out.println("product_name--->" + body);
            System.out.println("ip--->" + ip);
            /*
             * 调用统一支付接口
             */

            String notifyUrl = Path.weixin_pay_notifyurl_hometown_coin;
            String openid = request.getParameter("openID");

            Map<String, String> map = WeixinUtils.payUnifiedorder(WXPayType.OAPay, body,
                    totalPrice, ip, out_trade_no, notifyUrl, openid);
            TreeMap<String, String> outParams = new TreeMap<>();
            if (null != map) {
                String app_id = map.get("appid");
                /*
                 * 获取预支付id
                 */
                String prepayid = map.get("prepay_id");
                /**
                 * 创建预支付sign签名
                 */
                String noceStr = RandomStringGenerator.getRandomStringByLength(32);
                String timeStamp = String.valueOf((System.currentTimeMillis() / 1000));

                List<NameValuePair> signParams = new LinkedList<NameValuePair>();
                signParams.add(new BasicNameValuePair("appId", app_id));
                signParams.add(new BasicNameValuePair("nonceStr", noceStr));
                signParams.add(new BasicNameValuePair("package", "prepay_id=" + prepayid));
                signParams.add(new BasicNameValuePair("signType", "MD5"));
                signParams.add(new BasicNameValuePair("timeStamp", timeStamp));
                String sign = WeixinUtils.genSign(signParams);

                /*
                 * 支付接口业务处理 weiXinService.payBackSerivce(signParams, map);
                 * 修改订单状态和库存 修改代金券
                 */

                /*
                 * 返回支付需要的全部参数
                 */
                outParams.put("retcode", "0");
                outParams.put("retmsg", "OK");
                outParams.put("appid", app_id);
                outParams.put("noncestr", noceStr);
                outParams.put("partnerid", Constants.OA_MCH_ID);
                outParams.put("package", "prepay_id=" + prepayid);
                outParams.put("prepayid", prepayid);
                outParams.put("out_trade_no", out_trade_no);
                outParams.put("timestamp", timeStamp);
                outParams.put("sign_type", "MD5");
                outParams.put("sign", sign);
            } else {
                outParams.put("retcode", "-1");
                outParams.put("retmsg", "错误：获取不到Token");
            }
            Gson gson = new Gson();
            RemoteUtil.response(response, gson.toJson(outParams), 1, "返回成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void wxHcNotifyTest(String tradeNo, String cashFree) {
        int availe_amounts = 0;
        int freezon_amounts = 0;
        // 用交易号查充值记录
        ThRechargeRecord rechargeRecord = walletManager.rechargeRecordGetByTradeNo(tradeNo);
        int recordChannelAmounts = rechargeRecord.getChannelAmounts();
        int recordAmounts = rechargeRecord.getAmounts();
        // 获取乡币账户信息
        ThHcWallet hcWallet = walletManager.getWalletByUser(rechargeRecord.getUserId());
        // 比对支付前后金额（微信的是分还是元）
        if (Integer.parseInt(cashFree) != recordChannelAmounts) {
            logger.warn("订单金额异常");
            return;
        }
        // 用充值乡币 - 计算可用和冻结金额
        if (recordAmounts >= 10000 && recordAmounts < 50000) {
            availe_amounts = recordAmounts - 2000;
            freezon_amounts = 2000;
        } else if (recordAmounts >= 50000 && recordAmounts < 300000) {
            availe_amounts = recordAmounts - 10000;
            freezon_amounts = 10000;
        } else if (recordAmounts >= 300000) {
            availe_amounts = recordAmounts - 60000;
            freezon_amounts = 60000;
        } else {
            // 不满足以上金额，用8:2去算
            availe_amounts = recordAmounts / 10 * 8;
            freezon_amounts = recordAmounts / 10 * 2;
            logger.info("充值金额和等级对不上：" + recordAmounts + "分，8:2分配结果：" + availe_amounts + ":"
                    + freezon_amounts);
        }
        // 计算解冻时间 - 冻结时间以当前时间 + 1年为准（因为当前时间是支付完成时间）
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(new java.util.Date(System.currentTimeMillis()));
        gc.add(1, +1); //加一年
        java.util.Date dueTime = gc.getTime();
        // 组装冻结金额记录
        ThFrozenRecord frozenRecord = new ThFrozenRecord();
        frozenRecord.setAmounts(freezon_amounts);
        frozenRecord.setDueTime(dueTime);
        frozenRecord.setState(1);
        frozenRecord.setWalletId(hcWallet.getId());
        frozenRecord.setCreatedAt(new java.util.Date(System.currentTimeMillis()));
        // 获取等级规则
        int levelId = 0;
        if (rechargeRecord.getAmounts() >= 10000 && rechargeRecord.getAmounts() < 50000) {
            levelId = 1;
        } else if (rechargeRecord.getAmounts() >= 50000 && rechargeRecord.getAmounts() < 300000) {
            levelId = 2;
        } else if (rechargeRecord.getAmounts() >= 300000) {
            levelId = 3;
        }
        logger.info("升级判定为：" + levelId);
        logger.info("账户金额：" + hcWallet.getAvaileAmounts() + "，本次可用：" + availe_amounts + "分，本次冻结："
                + freezon_amounts + "分");
        //		try {
        // 更新充值记录状态
        walletManager.rechargeRecordUpdate(tradeNo, 2);
        logger.info("充值记录：" + tradeNo + "，状态变更为：成功");
        // 修改乡币账户金额
        walletManager.hcWalletUpdate(rechargeRecord.getUserId(), hcWallet.getAvaileAmounts()
                        + availe_amounts,
                hcWallet.getFreezonAmounts() + freezon_amounts);
        logger.info("账户编号：" + frozenRecord.getWalletId() + "可用金额增加：" + availe_amounts + "分，冻结金额增加："
                + freezon_amounts + "分");
        // 插入冻结金额记录
        walletManager.freezonRecordCreate(frozenRecord);
        logger.info("增加一笔" + frozenRecord.getAmounts() + "分的冻结记录");
        // 开通成为分销商
        if (levelId != 0) {
            logger.info("本次预存可升级为：" + levelId);
            ThSubUnderwriters subUnd = subUnderwritingManager.subUnderwriterGet(rechargeRecord
                    .getUserId());
            logger.info("执行过了：" + rechargeRecord.getUserId());
            if (subUnd == null) {
                logger.info("创建代言人账户 - 开始");
                subUnderwritingManager.subUnderwriterAdd(rechargeRecord.getUserId());
                logger.info("创建代言人账户 - 结束");
            } else {
                logger.info("有代言人记录：" + subUnd.getId());
            }
        }
        // 升级
        ClientInfo client = accountManager.getInfo(rechargeRecord.getUserId());
        // 当前等级小于需升级的等级，才会执行升级操作
        if (client.getLevelId() < levelId) {
            accountManager.updateLevel(rechargeRecord.getUserId(), levelId);
            logger.info("用户：" + rechargeRecord.getUserId() + "，升为：" + levelId + "级");

            // 加入升级模板消息推送
            ThClientPlatforms clientPlatform = accountManager
                    .getClientPlatformByUserId(rechargeRecord.getUserId());
            if (clientPlatform != null) {
                ThUserLevels level = accountManager.userLevelGet(levelId);
                TemplateMessageUtil.sendLevelUpMessage(clientPlatform.getOpenId(),
                        client.getName(), level.getTitle());
            }
        }

        // 操作成功，返回微信SUCCESS
        //			response.resetBuffer();
        //			response.setContentType("text/xml; charset=UTF-8");
        //			String returnXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        //
        //			PrintWriter writer;
        //			try {
        //				writer = response.getWriter();
        //				writer.print(returnXml);
        //				writer.flush();
        //			} catch (IOException e) {
        //				// TODO Auto-generated catch block
        //				e.printStackTrace();
        //				logger.info("微信回调 - 返回值写入失败：" + e.getMessage() +"，原因：" + e.getCause());
        //			}
        //		} catch (Exception e) {
        //			// TODO Auto-generated catch block
        //			e.printStackTrace();
        //			logger.info("回调事务处理失败：" + e.getMessage() +"，原因：" + e.getCause());
        //		}
    }

    /**
     * 乡币微信支付通知。
     *
     * @param request  the request
     * @param response the response
     */
    @SuppressWarnings({"unchecked", "deprecation"})
    public void wxHcNotify(HttpServletRequest request, HttpServletResponse response) {
        logger.info("=========== 乡币微信通知 - 来了 ===========");
        InputStream inputStream = null;
        Map<String, String> map = null;
        try {
            // 解析结果存储在HashMap
            map = new HashMap<String, String>();
            inputStream = request.getInputStream();
            // 读取输入流
            SAXReader reader = new SAXReader();
            Document document = reader.read(inputStream);
            // 得到xml根元素
            Element root = document.getRootElement();
            // 得到根元素的所有子节点
            List<Element> elementList = root.elements();
            // 遍历所有子节点
            for (Element e : elementList)
                map.put(e.getName(), e.getText());
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            // 释放资源
            try {
                if (inputStream != null) {
                    inputStream.close();
                    inputStream = null;
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        /*
         * map处理
         */
        if ("SUCCESS".equals(map.get("return_code"))) {
            String tradeNo = map.get("out_trade_no");
            String cashFree = map.get("cash_fee");
            int availe_amounts = 0;
            int freezon_amounts = 0;
            // 用交易号查充值记录
            ThRechargeRecord rechargeRecord = walletManager.rechargeRecordGetByTradeNo(tradeNo);
            int recordChannelAmounts = rechargeRecord.getChannelAmounts();
            int recordAmounts = rechargeRecord.getAmounts();
            // 获取乡币账户信息
            ThHcWallet hcWallet = walletManager.getWalletByUser(rechargeRecord.getUserId());
            // 比对支付前后金额（微信的是分还是元）
            if (Integer.parseInt(cashFree) != recordChannelAmounts) {
                logger.warn("订单金额异常");
                return;
            }
            // 用充值乡币 - 计算可用和冻结金额
            if (recordAmounts >= 10000 && recordAmounts < 50000) {
                availe_amounts = recordAmounts - 2000;
                freezon_amounts = 2000;
            } else if (recordAmounts >= 50000 && recordAmounts < 300000) {
                availe_amounts = recordAmounts - 10000;
                freezon_amounts = 10000;
            } else if (recordAmounts >= 300000) {
                availe_amounts = recordAmounts - 60000;
                freezon_amounts = 60000;
            } else {
                // 不满足以上金额，用8:2去算
                availe_amounts = recordAmounts / 10 * 8;
                freezon_amounts = recordAmounts / 10 * 2;
                logger.info("充值金额和等级对不上：" + recordAmounts + "分，8:2分配结果：" + availe_amounts + ":"
                        + freezon_amounts);
            }
            // 计算解冻时间 - 冻结时间以当前时间 + 1年为准（因为当前时间是支付完成时间）
            GregorianCalendar gc = new GregorianCalendar();
            gc.setTime(new java.util.Date(System.currentTimeMillis()));
            gc.add(1, +1); //加一年
            java.util.Date dueTime = gc.getTime();
            // 组装冻结金额记录
            ThFrozenRecord frozenRecord = new ThFrozenRecord();
            frozenRecord.setAmounts(freezon_amounts);
            frozenRecord.setDueTime(dueTime);
            frozenRecord.setState(1);
            frozenRecord.setWalletId(hcWallet.getId());
            frozenRecord.setCreatedAt(new java.util.Date(System.currentTimeMillis()));
            // 获取等级规则
            int levelId = 0;
            if (rechargeRecord.getAmounts() >= 10000 && rechargeRecord.getAmounts() < 50000) {
                levelId = 1;
            } else if (rechargeRecord.getAmounts() >= 50000 && rechargeRecord.getAmounts() < 300000) {
                levelId = 2;
            } else if (rechargeRecord.getAmounts() >= 300000) {
                levelId = 3;
            }
            logger.info("升级判定为：" + levelId);
            logger.info("账户金额：" + hcWallet.getAvaileAmounts() + "，本次可用：" + availe_amounts
                    + "分，本次冻结：" + freezon_amounts + "分");
            try {
                // 更新充值记录状态
                walletManager.rechargeRecordUpdate(tradeNo, 2);
                logger.info("充值记录：" + tradeNo + "，状态变更为：成功");
                // 修改乡币账户金额
                walletManager.hcWalletUpdate(rechargeRecord.getUserId(),
                        hcWallet.getAvaileAmounts() + availe_amounts, hcWallet.getFreezonAmounts()
                                + freezon_amounts);
                logger.info("账户编号：" + frozenRecord.getWalletId() + "可用金额增加：" + availe_amounts
                        + "分，冻结金额增加：" + freezon_amounts + "分");
                // 插入冻结金额记录
                walletManager.freezonRecordCreate(frozenRecord);
                logger.info("增加一笔" + frozenRecord.getAmounts() + "分的冻结记录");
                // 开通成为分销商
                if (levelId != 0) {
                    logger.info("本次预存可升级为：" + levelId);
                    ThSubUnderwriters subUnd = subUnderwritingManager
                            .subUnderwriterGet(rechargeRecord.getUserId());
                    logger.info("执行过了：" + rechargeRecord.getUserId());
                    if (subUnd == null) {
                        logger.info("创建代言人账户 - 开始");
                        subUnderwritingManager.subUnderwriterAdd(rechargeRecord.getUserId());
                        logger.info("创建代言人账户 - 结束");
                    } else {
                        logger.info("有代言人记录：" + subUnd.getId());
                    }
                }
                // 升级
                ClientInfo client = accountManager.getInfo(rechargeRecord.getUserId());
                // 当前等级小于需升级的等级，才会执行升级操作
                if (client.getLevelId() < levelId) {
                    accountManager.updateLevel(rechargeRecord.getUserId(), levelId);
                    logger.info("用户：" + rechargeRecord.getUserId() + "，升为：" + levelId + "级");

                    // 加入升级模板消息推送
                    ThClientPlatforms clientPlatform = accountManager
                            .getClientPlatformByUserId(rechargeRecord.getUserId());
                    if (clientPlatform != null) {
                        ThUserLevels level = accountManager.userLevelGet(levelId);
                        TemplateMessageUtil.sendLevelUpMessage(clientPlatform.getOpenId(),
                                client.getName(), level.getTitle());
                    }
                }
                // 操作成功，返回微信SUCCESS
                response.resetBuffer();
                response.setContentType("text/xml; charset=UTF-8");
                String returnXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

                PrintWriter writer;
                try {
                    writer = response.getWriter();
                    writer.print(returnXml);
                    writer.flush();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    logger.info("微信回调 - 返回值写入失败：" + e.getMessage() + ",原因：" + e.getCause());
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                logger.info("回调事务处理失败：" + e.getMessage() + ",原因：" + e.getCause());
            }
        } else {
            logger.info("乡币微信支付失败：" + map.get("return_code"));
        }
        logger.info("=========== 乡币微信通知 - 完成 ===========");
    }

    public String dateTransfer(java.util.Date date) {
        String dateStr = "";
        //format的格式可以任意   
        DateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        try {
            dateStr = sdf.format(date);
            return dateStr;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取用户消费记录。
     *
     * @param request  the request
     * @param response the response
     */
    public void userConsumeRecordsGet(HttpServletRequest request, HttpServletResponse response) {
        String userID = request.getParameter("userID");
        PageUtil page = new PageUtil(Integer.parseInt(request.getParameter("page")));
        if (userID != null && userID != "") {
            List<ThOutcomeRecord> recordList = walletManager.getOutcomeRecordsByUser(
                    Integer.parseInt(userID), page);
            RemoteUtil.response(response, recordList, 1, "操作成功");
        } else {
            RemoteUtil.response(response, "", -1, "参数缺失");
        }
    }

    /**
     * 获取请求方ip。
     *
     * @param request the request
     * @return the
     */
    public String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = "192.168.1.1"; // 实在出问题时没办法
        }

        int commaOffset = ip.indexOf(',');
        if (commaOffset < 0) {
            return ip;
        } else {
            return ip.substring(0, commaOffset);
        }
    }

    /**
     * Gets the wallet.
     *
     * @param request  the request
     * @param response the response
     * @return the wallet
     */
    // 获取钱包消息
    public void getWallet(HttpServletRequest request, HttpServletResponse response) {
        String userID = request.getParameter("userID");
        /*
         * 获取钱包金额 获取礼品卡和代金券的数量
         */
        WalletCash cash = walletManager.getWalletCash(Integer.parseInt(userID));
        int couponNumber = walletManager.getCouponNumber(Integer.parseInt(userID));
        WalletGiftCardCount cardCount = walletManager.getgiftCardCount(Integer.parseInt(userID));

        JsonWallet wallet = new JsonWallet();
        if (cash == null) {
            wallet.setCash(0);
        } else {
            wallet.setCash(cash.getMoney());
        }

        wallet.setCouponNumber(couponNumber);
        if (cardCount != null) {
            wallet.setGiftCardMoney(cardCount.getMoney());
        } else {
            wallet.setGiftCardMoney(0);
        }
        RemoteUtil.response(response, wallet, 1, "返回成功");
    }

    /**
     * Wallet list.
     *
     * @param request  the request
     * @param response the response
     */
    // 获取代金券和购物卡列表
    public void walletList(HttpServletRequest request, HttpServletResponse response) {
        String userID = request.getParameter("userID");
        String orderID = request.getParameter("orderID");
        /*
         * 获取钱包金额获取礼品卡和代金券的数量
         */
        String cPage = request.getParameter("page");
        PageUtil page = new PageUtil(Integer.parseInt(cPage));

        String type = request.getParameter("type");
        List<WalletCoupon> couponList;
        List<WalletGiftCard> cardList;

        switch (Integer.parseInt(type)) {
            case 0:
                couponList = walletManager.couponList(Integer.parseInt(userID), page);
                RemoteUtil.response(response, couponList, 1, "返回成功");
                break;
            case 1:
                cardList = walletManager.cardList(Integer.parseInt(userID), page, 0, 1);
                RemoteUtil.response(response, cardList, 1, "返回成功");
                break;
            case 2:
                cardList = walletManager.cardList(0, page, Integer.parseInt(orderID), 2);
                RemoteUtil.response(response, cardList, 1, "返回成功");
                break;
        }
    }

    // 礼品卡购买
    // public void giftcardBuy(HttpServletRequest request, HttpServletResponse
    // response) {
    // String ip = request.getParameter("ip");
    // String price = request.getParameter("price");
    // /**
    // * 先创建及礼品卡订单 在创建礼品卡
    // */
    // String money = request.getParameter("money");
    // String userID = request.getParameter("userID");
    // String number = request.getParameter("number");
    //
    // // GiftCardOrder order = new GiftCardOrder();
    //
    // GiftCardOrder order = (GiftCardOrder) RemoteUtil.request(request, new
    // GiftCardOrder());
    // // order.setUserID(Integer.parseInt(userID));
    // // order.setMoney(Float.parseFloat(money));
    // // order.setStation(0);//未激活
    // // order.setNumber(Integer.parseInt(number));
    //
    // // 创建礼品卡订单
    // opTag = walletManager.addGiftcradOrder(order);
    // if (!opTag) {
    // RemoteUtil.response(response, null, -1, "操作失败");
    // return;
    // }
    //
    // long startTime = System.currentTimeMillis();// 开始时间
    // // 有效期三年
    // long endTime = TimeUtil.getEndTime(startTime, 1, 3); // 结束时间
    //
    // for (int i = 1; i <= Integer.parseInt(number); i++) {
    // WalletGiftCard card = (WalletGiftCard) RemoteUtil.request(request, new
    // WalletGiftCard());
    // card.setStartTime(System.currentTimeMillis());
    // card.setEndTime(endTime);
    // card.setOrderID(order.getOrderID());// 订单ID
    // card.setMoney(Float.parseFloat(price));// 礼品卡大家
    // card.setActivation(0);
    //
    // card.setBuyer(Integer.parseInt(userID));// 购买者
    // String code = Code.sixNumberCode();
    // card.setActivationCode(code);// 六位数密码
    //
    // walletManager.addWalletGiftCard(card);// 创建礼品卡
    // }
    //
    // String body = "乡味汇礼品卡：" + money + "￥"; // body
    // int totalPrice = (int) (Integer.parseInt(money) * 100);// 以分为单位
    // // int fakePrice = 1;//一分钱
    // pay(totalPrice, body, ip, order.getOrderID() + "", request, response);
    //
    // }

    /**
     * Giftcard order list.
     *
     * @param request  the request
     * @param response the response
     */
    public void giftcardOrderList(HttpServletRequest request, HttpServletResponse response) {
        String userID = request.getParameter("userID");
        String cPage = request.getParameter("page");

        PageUtil page = new PageUtil(Integer.parseInt(cPage));
        List<GiftCardOrder> orderList = walletManager.giftcardOrderList(Integer.parseInt(userID),
                page);
        RemoteUtil.response(response, orderList, 1, "返回成功");
    }

    /**
     * Giftcard order code.
     *
     * @param request  the request
     * @param response the response
     */
    public void giftcardOrderCode(HttpServletRequest request, HttpServletResponse response) {
        String orderID = request.getParameter("orderID");
        String userID = request.getParameter("userID");

        GiftCardOrder order = walletManager.getGiftCardOrder(Integer.parseInt(orderID),
                Integer.parseInt(userID));
        if (order == null) {
            RemoteUtil.response(response, null, 0, "订单不存在");
            return;
        }

        // 六位数的随机验证码
        // TODO [String code = Code.sixNumberCode()]
        String code = "123456";
        opTag = walletManager.updateCardCode(Integer.parseInt(orderID), code);
        if (opTag) {
            RemoteUtil.response(response, null, 1, "返回成功");
            // 获取手机号
            String phone = accountManager.getAccount(null, Integer.parseInt(userID)).getPhone();
            // 发短信
            // TODO [MSGManager.giftcradOrderActiveMSG(phone, order.getOrderID() + "", code)]
        } else {
            RemoteUtil.response(response, null, -1, "返回失败");
        }
    }

    /**
     * 礼品卡订单激活
     *
     * @param request  the request
     * @param response the response
     */
    public void giftcardOrderActive(HttpServletRequest request, HttpServletResponse response) {
        // 一分钟
        long oneMinute = 1 * 60 * 1000;
        String orderID = request.getParameter("orderID");
        String code = request.getParameter("code");
        String userID = request.getParameter("userID");
        GiftCardOrder order = walletManager.getGiftCardOrder(Integer.parseInt(orderID),
                Integer.parseInt(userID));

        if (order == null) {
            RemoteUtil.response(response, null, 0, "订单不存在");
            return;
        }

        if (System.currentTimeMillis() - order.getOpTime() < oneMinute
                && (code.equals(order.getCode()))) {
            opTag = walletManager.updateCardCodeStation(Integer.parseInt(orderID), 2);
            if (opTag) {
                RemoteUtil.response(response, null, 1, "操作成功");
            } else {
                RemoteUtil.response(response, null, -1, "操作失败");
            }
        } else {
            RemoteUtil.response(response, null, -1, "操作失败");
        }
    }

    /**
     * Pay.
     *
     * @param totalPrice   the total price
     * @param body         the body
     * @param ip           the ip
     * @param out_trade_no the out trade no
     * @param request      the request
     * @param response     the response
     */
    public void pay(int totalPrice, String body, String ip, String out_trade_no,
                    HttpServletRequest request, HttpServletResponse response) {
        System.out.println("----创建微信预付定单-----");
        try {
            System.out.println("totalPrice--->" + totalPrice);
            System.out.println("product_name--->" + body);
            System.out.println("ip--->" + ip);
            /*
             * 调用统一支付接口
             */
            String notifyUrl = Path.weixin_pay_notifyurl_giftCard;

            Map<String, String> map = WeixinUtils.payUnifiedorder(WXPayType.AppPay, body,
                    totalPrice, ip, out_trade_no, notifyUrl, null);
            TreeMap<String, String> outParams = new TreeMap<>();
            if (null != map) {
                String app_id = map.get("appid");
                /*
                 * 获取预支付id
                 */
                String prepayid = map.get("prepay_id");
                /**
                 * 创建预支付sign签名
                 */
                String noceStr = RandomStringGenerator.getRandomStringByLength(32);
                String timeStamp = String.valueOf((System.currentTimeMillis() / 1000));
                List<NameValuePair> signParams = new LinkedList<>();
                signParams.add(new BasicNameValuePair("appid", app_id));
                signParams.add(new BasicNameValuePair("noncestr", noceStr));
                signParams.add(new BasicNameValuePair("package", "Sign=WXPay"));
                signParams.add(new BasicNameValuePair("partnerid", Constants.MCH_ID));
                signParams.add(new BasicNameValuePair("prepayid", prepayid));
                signParams.add(new BasicNameValuePair("timestamp", timeStamp));

                String sign = WeixinUtils.genSign(signParams);

                /*
                 * 支付接口业务处理 weiXinService.payBackSerivce(signParams, map);
                 */

                /**
                 * 返回手机端支付需要的全部参数
                 */
                outParams.put("retcode", "0");
                outParams.put("retmsg", "OK");
                outParams.put("appid", Constants.APP_ID);
                outParams.put("noncestr", noceStr);
                outParams.put("partnerid", Constants.MCH_ID);
                outParams.put("package", "Sign=WXPay");
                outParams.put("prepayid", prepayid);
                outParams.put("out_trade_no", out_trade_no);
                outParams.put("timestamp", timeStamp);
                outParams.put("sign", sign);

                String param = "&giftCardID=" + out_trade_no;
                outParams.put("aliPayNotifyUrl", Path.ali_pay_notifyurl_giftCard + param);
            } else {
                outParams.put("retcode", "-1");
                outParams.put("retmsg", "错误：获取不到Token");
            }

            Gson gson = new Gson();
            RemoteUtil.response(response, gson.toJson(outParams), 1, "返回成功");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Ali notify.
     *
     * @param request  the request
     * @param response the response
     */
    // 阿里通知
    public void aliNotify(HttpServletRequest request, HttpServletResponse response) {
        String tradeNo = request.getParameter("giftCardID");
        if (tradeNo == null) {
            return;
        }

        opTag = walletManager.updateCardCodeStation(Integer.parseInt(tradeNo), 1);// 设置礼品卡订单状态已支付

        // opTag =
        // walletManager.updateCardCodeStation(Integer.parseInt(giftCardID),
        // 1);//设置礼品卡订单状态已支付
        //// opTag =
        // walletManager.updateGiftCardOwnerASBuyer(Integer.parseInt(giftCardID));
        //
        //// opTag =
        // walletManager.updateCardCodeStation(Integer.parseInt(tradeNo),
        // 1);//设置礼品卡订单状态已支付
        //
        // if(opTag){
        // WalletGiftCard card=
        // walletManager.getGiftCard(Integer.parseInt(giftCardID));
        // int userID = card.getBuyer();//获取所有这的UserID
        // //获取所有者的手机号
        // String phone = accountManager.getAccount(null, userID).getPhone();
        // //发送短信
        // sendMessage(card.getCardID(), phone);
        // }
    }

    /**
     * Wx notify.
     *
     * @param request  the request
     * @param response the response
     */
    // 微信通知
    @SuppressWarnings("unchecked")
    public void wxNotify(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("-------微信通知来了---------");
        InputStream inputStream = null;
        Map<String, String> map = null;
        try {
            // 解析结果存储在HashMap
            map = new HashMap<String, String>();
            inputStream = request.getInputStream();
            // 读取输入流
            SAXReader reader = new SAXReader();
            Document document = reader.read(inputStream);
            // 得到xml根元素
            Element root = document.getRootElement();
            // 得到根元素的所有子节点
            List<Element> elementList = root.elements();
            // 遍历所有子节点
            for (Element e : elementList)
                map.put(e.getName(), e.getText());
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            // 释放资源
            try {
                if (inputStream != null) {
                    inputStream.close();
                    inputStream = null;
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        /*
         * map处理
         */
        if ("SUCCESS".equals(map.get("return_code"))) {
            String tradeNo = map.get("out_trade_no");// 这个tradeNo就是giftCardID
            /*
             * 修改该wallet的帐号为UserID，和buyerID相同
             */
            opTag = walletManager.updateCardCodeStation(Integer.parseInt(tradeNo), 1);// 设置礼品卡订单状态已支付
            if (opTag) {// 操作成功
                /*
                 * 操作成功，返回微信SUCCESS
                 */
                response.resetBuffer();
                response.setContentType("text/xml; charset=UTF-8");
                String returnXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

                PrintWriter writer;
                try {
                    writer = response.getWriter();
                    writer.print(returnXml);
                    writer.flush();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Send message.
     *
     * @param cardID the card ID
     * @param phone  the phone
     */
    // 发送短信
    public void sendMessage(int cardID, String phone) {
        //TODO [String activationCode = Code.sixNumberCode()]
        String activationCode = "123456";
        /*
         * 先修改一下密码
         */
        walletManager.setGiftcardCode(cardID, activationCode);
        //TODO [MSGManager.activeMSG(phone, cardID + "", activationCode)]
    }

    /**
     * Card activation.
     *
     * @param request  the request
     * @param response the response
     */
    // 礼品卡激活
    public void cardActivation(HttpServletRequest request, HttpServletResponse response) {
        String userID = request.getParameter("userID");
        String code = request.getParameter("code");
        String cardID = request.getParameter("cardID");
        /*
         * 礼品卡激活之后需要想账户里面充值
         */

        // 已经激活的礼品卡激活失败
        WalletGiftCard card = walletManager.getGiftCard(Integer.parseInt(cardID));
        if (card.getActivation() == 1) {
            RemoteUtil.response(response, null, -1, "操作失败");
            return;
        }

        opTag = walletManager.cardActivation(Integer.parseInt(userID), Integer.parseInt(cardID),
                code);
        if (opTag) {
            RemoteUtil.response(response, null, 1, "操作成功");
            /*
             * 帐号充值
             */
            // WalletGiftCard card=
            // walletManager.getGiftCard(Integer.parseInt(cardID));
            walletManager.updategiftCardCount(Integer.parseInt(userID), card.getMoney());
        } else {
            RemoteUtil.response(response, null, -1, "操作失败");
        }
    }

}
